/******************************************************************************
 *                                                                            *
 *                          OS main body file                                 *
 *                                                                            *
 *----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*
 *              --- Included files and compilation variables ---              *
 *----------------------------------------------------------------------------*/

#include "OS.h"
#include <string.h>

#include "OS_Task.h"

#pragma CODE_SEG NON_BANKED

/*----------------------------------------------------------------------------*
 *                     --- Local constants & typedefs ---                     *
 *----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*
 *                             --- Variables ---                              *
 *----------------------------------------------------------------------------*/

// OS_Control struct is not initialised because of its variable size according to OS facilities used
// Init is made by memset in OS_Init.
OS_ControlType OS_Control;

/*----------------------------------------------------------------------------*
 *                    --- Local functions declaration ---                     *
 *----------------------------------------------------------------------------*/

static void OS_CheckTasks(void);

/*----------------------------------------------------------------------------*
 *                          --- Local functions ---                           *
 *----------------------------------------------------------------------------*/

/******************************************************************************
 * Function  : OS_CheckTasks
 *
 * Role      : Check tasks
 *				This function is called periodically, at each system tick
 *              It will update task schedule counter but will not schedule tasks by itself
 *
 *-----------------------------------------------------------------------------
 * Entry     : <<entry parameters>>
 *
 * Exit      : <<exit parameters>>
 *
 *-----------------------------------------------------------------------------
 * globals   : r/w Name Of Variable    Range       Description
 *             --- ------------------  ---------   ----------------------------
 *
 *
 ******************************************************************************/
#pragma INLINE
void OS_CheckTasks(void)
{
    register OS_TaskType* pThisTask = OS_TaskArray;

    while (pThisTask!=&OS_TaskArray[OS_MaxTask])
    {
        if ( pThisTask->Expiration!=0 )
        {
            --pThisTask->Expiration;
            if ( pThisTask->Expiration==0 )
            {
                ++pThisTask->Schedule;
                ++OS_Control.TasksToSchedule;
                pThisTask->Expiration = pThisTask->Reload;
            }
        }
        ++pThisTask;
    }
}

/*----------------------------------------------------------------------------*
 *                          --- Public functions ---                          *
 *----------------------------------------------------------------------------*/


 /******************************************************************************
 * Function  : OS_Init
 *
 * Role      :
 *
 *-----------------------------------------------------------------------------
 * Entry     : <<entry parameters>>
 *
 * Exit      : <<exit parameters>>
 *
 *-----------------------------------------------------------------------------
 * globals   : r/w Name Of Variable    Range       Description
 *             --- ------------------  ---------   ----------------------------
 *
 *
 ******************************************************************************/
void OS_Init(void)
{
    // Initialised main OS data structure to 0
    (void)memset(&OS_Control, 0, (size_t)sizeof(OS_Control));

    OS_StartupHook();
	
}

/******************************************************************************
 * Function  : OS_Run
 *
 * Role      : Run ...
 *
 *-----------------------------------------------------------------------------
 * Entry     : <<entry parameters>>
 *
 * Exit      : <<exit parameters>>
 *
 *-----------------------------------------------------------------------------
 * globals   : r/w Name Of Variable    Range       Description
 *             --- ------------------  ---------   ----------------------------
 *
 *
 ******************************************************************************/

void OS_Run(void)
{
	while (1)
	{
		// Check System tasks for scheduling
	    if (OS_Control.TasksToSchedule!=0)
	    {
	        // At least one task to schedule
	        OS_ScheduleTasks();
	    }
	}
}

/******************************************************************************
 * Function  : SysTick
 *
 * Role      : System tick
 *
 *-----------------------------------------------------------------------------
 * Entry     : <<entry parameters>>
 *
 * Exit      : <<exit parameters>>
 *
 *-----------------------------------------------------------------------------
 * globals   : r/w Name Of Variable    Range       Description
 *             --- ------------------  ---------   ----------------------------
 *
 *
 ******************************************************************************/

__interrupt void OS_SysTick(void)
{
	OS_PRE_SYSTICK();

	// This function must be called cyclic by hardware timer
	OS_Control.Tick++;

	OS_CheckTasks();

	OS_POST_SYSTICK();
}


/******************************************************************************
 * Function  : OS_Wait
 *
 * Role      : Activ wait n us
 *
 *-----------------------------------------------------------------------------
 * Entry     : none
 *
 * Exit      : none
 *
 *-----------------------------------------------------------------------------
 * globals   : r/w Name Of Variable    Range       Description
 *             --- ------------------  ---------   ----------------------------
 *
 *
 ******************************************************************************/

void OS_Wait(OS_TimeType time)
{
    register OS_TimeType start = OS_GetFreeRunCounter();

    while ((OS_TimeType)(OS_GetFreeRunCounter()-start) < time );
}

#pragma CODE_SEG DEFAULT

/******************************************************************************
 *                               End of file                                  *
 ******************************************************************************/

